home *** CD-ROM | disk | FTP | other *** search
-
- ;
- ; Copyright (c) 1988 Commodore-Amiga, Inc.
- ;
- ; Executables based on this information may be used in software
- ; for Commodore Amiga computers. All other rights reserved.
- ;
- ; This information is provided "as is"; no warranties are made.
- ; All use is at your own risk, and no liability or responsibility is assumed.
- ;
-
- SECTION example,CODE
- ;=============================================================================
- ; An example to write to the CLI window every second until CTRL/C is pressed.
- ;=============================================================================
- NOLIST
- INCLUDE "exec/types.i"
- INCLUDE "exec/memory.i"
- INCLUDE "exec/interrupts.i"
- INCLUDE "hardware/intbits.i"
- INCLUDE "libraries/dos.i"
- LIST
-
- ; first we define the global data we will be using throughout the program
- STRUCTURE globals,0
- APTR SysLib exec library base
- APTR DosLib dos library base
- APTR IntServer pointer to our interrupt server
- UWORD Ticks number of ticks that occured
- ULONG OutHandle the output file handle for writing
- APTR ThisTask current task address
- ULONG WaitMask sigs we will wait for
- ULONG TickMask what int handler signals task with
- LABEL globals_SIZEOF
-
- ; now we define what external library routines we will be using in this code
- XREF _AbsExecBase,_LVOOpenLibrary,_LVOCloseLibrary
- XREF _LVOAllocMem,_LVOFreeMem,_LVOFindTask
- XREF _LVOAddIntServer,_LVORemIntServer
- XREF _LVOAllocSignal,_LVOWait,_LVOSignal
- XREF _LVOOutput,_LVOWrite
-
- ;============================================================================
- ;Standard initialisation to get the global data space and libraries required
- ;============================================================================
- Main moveq.l #(globals_SIZEOF/2)-1,d0
- 10$ clr.w -(sp) clear global space
- dbra d0,10$
- movea.l sp,a5 a5 always points to globals
- movea.l _AbsExecBase,a6 get exec.library base
- move.l a6,SysLib(a5) and stash it for later
-
- lea.l DosName(pc),a1 open dos.library
- moveq.l #33,d0 version 33 or greater
- jsr _LVOOpenLibrary(a6)
- move.l d0,DosLib(a5) save the pointer
- beq Exit didn't get it
-
- ;============================================================================
- ; now get the memory for the interrupt server and initialise the data area
- ;============================================================================
- moveq.l #IS_SIZE,d0 size of server node
- move.l #MEMF_PUBLIC!MEMF_CLEAR,d1
- jsr _LVOAllocMem(a6) get some memory for it
- move.l d0,IntServer(a5) save pointer to server
- beq Exit didn't get server memory
- movea.l d0,a1 fill in the structure
- move.b #NT_INTERRUPT,LN_TYPE(a1) set the node type
- move.b #20,LN_PRI(a1) set priority of the server
- lea.l IntServerName(pc),a0 set up a name for the node
- move.l a0,LN_NAME(a1)
- move.l a5,IS_DATA(a1) server can see globals
- lea.l IntServerCode(pc),a0 set up pointer to the code
- move.l a0,IS_CODE(a1) in server init complete
-
- ;============================================================================
- ; do all the DOS initialisation to find the output handle and write a message
- ;============================================================================
- movea.l DosLib(a5),a6 using dos library now
- jsr _LVOOutput(a6) get output file handle
- move.l d0,OutHandle(a5) and save it
- move.l d0,d1 writing to stdout
- lea.l Msg1(pc),a0
- move.l a0,d2 pointer to msg in d2
- moveq.l #Msg1End-Msg1,d3 length in d3
- jsr _LVOWrite(a6) write out the message
-
- ;============================================================================
- ; get a signal bit that the interrupt server can signal us with every second
- ;============================================================================
- movea.l SysLib(a5),a6 using exec.library again
- moveq.l #-1,d0 any signal will do
- jsr _LVOAllocSignal(a6)
- moveq.l #0,d1 convert signum to a mask
- bset.l d0,d1
- move.l d1,TickMask(a5) and save it for int server
- ori.l #SIGBREAKF_CTRL_C,d1 we're waiting for CTRL/C too
- move.l d1,WaitMask(a5) stash combined sig bits
-
- ;============================================================================
- ; generate a pointer to this task so that the interrupt server can find us.
- ;============================================================================
- suba.l a1,a1 find this task
- jsr _LVOFindTask(a6)
- move.l d0,ThisTask(a5) and stash the address
-
- ;============================================================================
- ; now that everything is initialised, its safe to add the interrupt server
- ;============================================================================
- move.w #60,Ticks(a5) initialise tick count
- movea.l IntServer(a5),a1 get the intserver node
- moveq.l #INTB_VERTB,d0 hooking into VBlank int
- jsr _LVOAddIntServer(a6) start it up
-
- ;============================================================================
- ; The main loop of this program. Waits for a signal from the interrupt server
- ; or from the user pressing CTRL/C and does the appropriate things.
- ;============================================================================
- WaitLoop move.l SysLib(a5),a6 using exec for Wait
- move.l WaitMask(a5),d0 get sigs we are waiting for
- jsr _LVOWait(a6) go to sleep
- btst.l #SIGBREAKB_CTRL_C,d0 did we get a CTRL/C ?
- bne.s Stopped yes, exit the program
-
- ;============================================================================
- ; we were woken up by the interrupt routine so print out the word tick!
- ;============================================================================
- movea.l DosLib(a5),a6 using dos.library again
- move.l OutHandle(a5),d1 writing to CLI window
- lea.l Msg2(pc),a0 printing this message
- move.l a0,d2
- moveq.l #Msg2End-Msg2,d3 this length
- jsr _LVOWrite(a6) write the message out
- bra.s WaitLoop and wait for more signals
-
- ;============================================================================
- ; user pressed CTRL/C so remove interrupt server and print the done message.
- ;============================================================================
- Stopped movea.l SysLib(a5),a6 using exec.library
- movea.l IntServer(a5),a1 removing this int server
- moveq.l #INTB_VERTB,d0 from this server chain
- jsr _LVORemIntServer(a6) remove it
-
- movea.l DosLib(a5),a6 now write out the done msg
- move.l OutHandle(a5),d1 writing to the CLI window
- lea.l Msg3(pc),a0 printing this message
- move.l a0,d2
- moveq.l #Msg3End-Msg3,d3 this length
- jsr _LVOWrite(a6) write it out
-
- ;============================================================================
- ; The main exit point of this program. It uses the fact that the global
- ; memory is zeroed at startup time to determine which resources have been
- ; opened or allocated. Cleanup is done in the same order as initialisation
- ; so that as soon as a zero value is found, cleanup is considered complete.
- ;============================================================================
- Exit movea.l SysLib(a5),a6 using exec for cleanups
- tst.l DosLib(a5) did we get dos.library ?
- beq.s ReallyExit no more cleanup needed
- movea.l DosLib(a5),a1 close dos library
- jsr _LVOCloseLibrary(a6)
-
- tst.l IntServer(a5) did we get mem for intserver
- beq.s ReallyExit no, so no more cleanup
- movea.l IntServer(a5),a1 free server memory
- moveq.l #IS_SIZE,d0
- jsr _LVOFreeMem(a6)
-
- ;============================================================================
- ; and the final exit point that cleans up our globals off the stack area.
- ;============================================================================
- ReallyExit lea.l globals_SIZEOF(sp),sp reclaim stack space
- moveq.l #0,d0 non error return for CLI
- rts bye-bye
-
-
- ;============================================================================
- ; This is the actual interrupt server that is called every 60th of a second
- ; on the vertical blank interrupt chain. It is entered with a1 pointing to
- ; our global data (because we put a5 into IS_DATA) and a6 pointing to exec.
- ;============================================================================
- IntServerCode move.l a6,-(sp)
- movea.l _AbsExecBase,a6
- subq.w #1,Ticks(a1) decrement the tick count
- bne.s IntDone not at 0 yet
-
- ; ticks reached 0 so send the appropriate signal to the main task
- move.w #60,Ticks(a1) re-initialise tick count
- move.l TickMask(a1),d0 we want to send this signal
- movea.l ThisTask(a1),a1 to this task
- jsr _LVOSignal(a6) so it wakes up
-
- ; we return 0 here so that other handlers get called too. A non zero return
- ; terminates the server chain and no server at a lower pri would get called
- IntDone moveq.l #0,d0 other handlers get a chance
- move.l (sp)+,a6
- rts
-
-
- ; Text used by the program. It's OK to put them here because they are static
- DosName DC.B 'dos.library',0
- CNOP 0,2
-
- IntServerName DC.B 'tick server',0
- CNOP 0,2
-
- Msg1 DC.B 'Interrupt server example starting',10
- Msg1End CNOP 0,2
-
- Msg2 DC.B 'tick!',10
- Msg2End CNOP 0,2
-
- Msg3 DC.B '******* B-O-O-O-O-O-O-O-M *******',10
- Msg3End CNOP 0,2
-
- END
-